﻿// Copyright (c) 2012-2013 fancidev
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

using System;
using System.Text;
using System.IO;

namespace Util.IO
{
    public enum Endian
    {
        Native = 0,
        Little = 1,
        Big = 2,
    }

    public static class EndianConverter
    {
        public static uint SwapBytes(uint x)
        {
            return (x >> 24) |
                   ((x >> 8) & 0x0000FF00) |
                   ((x << 8) & 0x00FF0000) |
                   (x << 24);
        }

        public static int SwapBytes(int x)
        {
            return (int)SwapBytes((uint)x);
        }

#if false
        public static ulong SwapBytes(ulong x)
        {
            // 7 6 5 4 | 3 2 1 0
            return (x >> 24) |
                   ((x >> 8) & 0x0000FF00) |
                   ((x << 8) & 0x00FF0000) |
                   (x << 24);
        }

        public static long SwapBytes(long x)
        {
            return (long)SwapBytes((ulong)x);
        }
#endif
    }

#if false
    public class BigEndianBinaryReader : BinaryReader
    {
        public BigEndianBinaryReader(Stream stream, Encoding encoding)
            : base(stream, encoding) { }

        public BigEndianBinaryReader(Stream stream)
            : base(stream) { }

        [CLSCompliant(false)]
        public override ushort ReadUInt16()
        {
            ushort x = base.ReadUInt16();
            return (ushort)((x >> 8) | (x << 8));
        }

        public override short ReadInt16()
        {
            return (short)this.ReadUInt16();
        }

        [CLSCompliant(false)]
        public override uint ReadUInt32()
        {
            uint x = base.ReadUInt32();
            return ((x & 0xFF000000) >> 24)
                 | ((x & 0x00FF0000) >> 8)
                 | ((x & 0x0000FF00) << 8)
                 | ((x & 0x000000FF) << 24);
        }

        public override int ReadInt32()
        {
            return (int)this.ReadUInt32();
        }

        [CLSCompliant(false)]
        public override ulong ReadUInt64()
        {
            ulong x = base.ReadUInt64();
            return ((x & 0xFF00000000000000) >> 56)
                 | ((x & 0x00FF000000000000) >> 40)
                 | ((x & 0x0000FF0000000000) >> 24)
                 | ((x & 0x000000FF00000000) >> 8)
                 | ((x & 0x00000000FF000000) << 8)
                 | ((x & 0x0000000000FF0000) << 24)
                 | ((x & 0x000000000000FF00) << 40)
                 | ((x & 0x00000000000000FF) << 56);
        }

        public override long ReadInt64()
        {
            return (long)this.ReadUInt64();
        }
    }
#endif
}
